<?php
/**
 * Abstract base class for constraints. which are placed upon any value.
 *
 * @category   Testing
 * @package    PHPUnit
 * @author     Jan Borsodi <jb@ez.no>
 *             Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @copyright  2002-2006 Sebastian Bergmann <sb@sebastian-bergmann.de>
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 * @version    Release: 3.0.0
 * @link       http://www.phpunit.de/
 * @since      Interface available since Release 3.0.0
 */
abstract class Constraint
{
    /**
     * Evaluates the constraint for parameter $other. Returns TRUE if the
     * constraint is met, FALSE otherwise.
     *
     * @param mixed $other Value or object to evaluate.
     * @return bool
     * @abstract
     */
    abstract public function evaluate($other);
    abstract public function toString();

    /**
     * Creates the appropriate exception for the constraint which can be caught
     * by the unit test system. This can be called if a call to evaluate() fails.
     *
     * @param   mixed   $other The value passed to evaluate() which failed the
     *                         constraint check.
     * @param   string  $description A string with extra description of what was
     *                               going on while the evaluation failed.
     * @param   boolean $not Flag to indicate negation.
     * @throws  ExpectationFailedException
     */
    public function fail($other, $description, $not = FALSE)
    {
        throw new ExpectationFailedException(
          $this->failureDescription($other, $description, $not)
        );
    }

    protected function failureDescription($other, $description, $not)
    {
        $failureDescription = sprintf(
          'Failed asserting that %s %s.',

           Type::toString($other),
           $this->toString()
        );

        if ($not) {
            $failureDescription = self::negate($failureDescription);
        }

        if (!empty($description)) {
            $failureDescription = $description . "\n" . $failureDescription;
        }

        return $failureDescription;
    }

    public static function negate($string)
    {
        return str_replace(
          array(
            'contains ',
            'exists',
            'has ',
            'is ',
            'matches '
          ),
          array(
            'does not contain ',
            'does not exist',
            'does not have ',
            'is not ',
            'does not match '
          ),
          $string
        );
    }
}

require_once 'Constraint/And.class.php';
require_once 'Constraint/ArrayHasKey.class.php';
require_once 'Constraint/ArrayNotHasNull.class.php';

require_once 'Constraint/FileExists.class.php';
require_once 'Constraint/GreaterThan.class.php';
require_once 'Constraint/IsAnything.class.php';
require_once 'Constraint/IsEqual.class.php';
require_once 'Constraint/IsIdentical.class.php';
require_once 'Constraint/IsInstanceOf.class.php';
require_once 'Constraint/IsType.class.php';
require_once 'Constraint/LessThan.class.php';
require_once 'Constraint/Not.class.php';
require_once 'Constraint/ObjectHasAttribute.class.php';
require_once 'Constraint/Or.class.php';
require_once 'Constraint/PCREMatch.class.php';
require_once 'Constraint/StringContains.class.php';
require_once 'Constraint/TraversableContains.class.php';
require_once 'Constraint/Xor.class.php';
?>
